package domain;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import exception.ClassDurationOverflowException;

public class Class implements Presentable {
	private final String DURATION_OVERFLOW = "Class duration can not exceed maximum duration of Discipline.";
	
	private String name;
	private Discipline discipline;
	private Professor professor;
	private List<PTime> freeSchedules;
	
	private HashMap<Integer, ArrayList<Schedule>> blockedSchedules;

	
	public Class(Discipline discipline, Professor professor, String name) {
		this.setDiscipline(discipline);
		this.setAccountable(professor);
		this.setName(name);
		this.setFreeSchedules(new ArrayList<PTime>());
		
		this.blockedSchedules = new HashMap<Integer, ArrayList<Schedule>>();

	}
	
	@Override
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Discipline getDiscipline() {
		return this.discipline;
	}
	
	public void setDiscipline(Discipline discipline) {
		this.discipline = discipline;
	}
	
	public List<PTime> getFreeSchedules() {
		return this.freeSchedules;
	}
	
	public void setFreeSchedules(List<PTime> freeSchedules) {
		this.freeSchedules = freeSchedules;
	}
	
	@Override
	public Professor getAccountable() {
		return professor;
	}

	@Override
	public void setAccountable(Accountable a) {
		this.professor = (Professor) a;
	}
	
	
	
	public  ArrayList<Schedule> getBlockedSchedules(Integer priorityLevel) {
		return blockedSchedules.get(priorityLevel);
	}
	
	public void addBlockedSchedule(Integer priorityLevel, Schedule schedule){
		if (blockedSchedules.containsKey(priorityLevel))blockedSchedules.get(priorityLevel).add(schedule);
		else{
			ArrayList<Schedule> newSchedules = new ArrayList<Schedule>();
			newSchedules.add(schedule);
			blockedSchedules.put(priorityLevel, newSchedules);
		}
	}
	
	public boolean validateSchedule(Schedule schedule) {
		if (blockedSchedules.containsValue(schedule))
			return false;

		return true;
	}

	
	@Override
	public PTime getTotalDurationOfPresentable() {
		PTime total = null;
		try {
			total = new PTime(0,0);
		} catch (Exception e) {	
		}
		for (PTime fst : this.getFreeSchedules()) {
			total = PTime.sum(total, fst);
		}
		return total;
	}

	@Override
	public void addFreeSchedule(PTime p) throws ClassDurationOverflowException {
		if (PTime.sum(p, this.getTotalDurationOfPresentable())
				.compareTo(this.getDiscipline().getTotalDurationForEachPresentable()) > 0) {
			throw new ClassDurationOverflowException(DURATION_OVERFLOW);
		}
		this.freeSchedules.add(p);
	}

	@Override
	public void removeFreeSchedule(PTime p) {
		for (PTime freeSchedule : this.getFreeSchedules()) {
			if (freeSchedule.equals(p)) {
				this.freeSchedules.remove(p);
			}
		}
	}
	
	@Override
	public String toString() {
		return this.getDiscipline().getName() + ": " + this.getName();
	}
	
	@Override
	public boolean equals(Object o) {
		if (this.getClass() != o.getClass()) {
			return false;
		}
		final Class c = (Class) o;
		return this.getName().equals(c.getName()) 
			&& this.getDiscipline().equals(c.getDiscipline())
			&& this.getAccountable().equals(c.getAccountable());
	}

}
